diff mbox

timezone: Remove TZNAME_MAX limit from sysconf [BZ #15576]

Message ID 20170307091350.7261B439942F6@oldenburg.str.redhat.com
State New
Headers show

Commit Message

Florian Weimer March 7, 2017, 9:13 a.m. UTC
glibc does not impose a limit, and POSIX does not allow a
sysconf limit which changes during the lifetime of a process.

2017-03-07  Florian Weimer  <fweimer@redhat.com>

	[BZ #15576]
	Remove TZNAME_MAX limit from sysconf.
	* include/time.h (__tzname_cur_max, __tzname_max): Remove
	declaration.
	* time/tzfile.c (__tzfile_read, __tzfile_default): Do not call
	compute_tzname_max.
	(compute_tzname_max): Remove.
	* time/tzset.c (__tzname_cur_max, __tzname_max): Remove.
	(update_vars): Do not update __tzname_cur_max.
	(tzset_internal): Remove argument.
	(__tzset): Adjust call to tzset_internal.
	(__tz_convert): Likewise.
	* posix/sysconf.c (__sysconf): Return -1 for _SC_TZNAME_MAX.
	* sysdeps/posix/sysconf.c (__sysconf): Likewise.
	* manual/conf.texi (Sysconf Definition): Update comment.

Comments

Adhemerval Zanella Netto March 7, 2017, 10:55 a.m. UTC | #1
LGTM.

On 07/03/2017 10:13, Florian Weimer wrote:
> glibc does not impose a limit, and POSIX does not allow a
> sysconf limit which changes during the lifetime of a process.
> 
> 2017-03-07  Florian Weimer  <fweimer@redhat.com>
> 
> 	[BZ #15576]
> 	Remove TZNAME_MAX limit from sysconf.
> 	* include/time.h (__tzname_cur_max, __tzname_max): Remove
> 	declaration.
> 	* time/tzfile.c (__tzfile_read, __tzfile_default): Do not call
> 	compute_tzname_max.
> 	(compute_tzname_max): Remove.
> 	* time/tzset.c (__tzname_cur_max, __tzname_max): Remove.
> 	(update_vars): Do not update __tzname_cur_max.
> 	(tzset_internal): Remove argument.
> 	(__tzset): Adjust call to tzset_internal.
> 	(__tz_convert): Likewise.
> 	* posix/sysconf.c (__sysconf): Return -1 for _SC_TZNAME_MAX.
> 	* sysdeps/posix/sysconf.c (__sysconf): Likewise.
> 	* manual/conf.texi (Sysconf Definition): Update comment.
> 
> diff --git a/include/time.h b/include/time.h
> index 684ceb8..6badf0e 100644
> --- a/include/time.h
> +++ b/include/time.h
> @@ -37,10 +37,6 @@ extern struct tm _tmbuf attribute_hidden;
>  /* Defined in tzset.c.  */
>  extern char *__tzstring (const char *string);
>  
> -/* Defined in tzset.c. */
> -extern size_t __tzname_cur_max attribute_hidden;
> -
> -
>  extern int __use_tzfile attribute_hidden;
>  
>  extern void __tzfile_read (const char *file, size_t extra,
> @@ -82,10 +78,6 @@ extern void __tzset (void);
>  /* Prototype for the internal function to get information based on TZ.  */
>  extern struct tm *__tz_convert (const time_t *timer, int use_localtime, struct tm *tp);
>  
> -/* Return the maximum length of a timezone name.
> -   This is what `sysconf (_SC_TZNAME_MAX)' does.  */
> -extern long int __tzname_max (void);
> -
>  extern int __nanosleep (const struct timespec *__requested_time,
>  			struct timespec *__remaining);
>  libc_hidden_proto (__nanosleep)
> diff --git a/manual/conf.texi b/manual/conf.texi
> index 78b7a4d..1fe75c2 100644
> --- a/manual/conf.texi
> +++ b/manual/conf.texi
> @@ -291,14 +291,10 @@ constants are declared in the header file @file{unistd.h}.
>  @safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
>  @c Some parts of the implementation open /proc and /sys files and dirs
>  @c to collect system details, using fd and stream I/O depending on the
> -@c case.  _SC_TZNAME_MAX calls __tzname_max, that (while holding a lock)
> -@c calls tzset_internal, that calls getenv if it's called the first
> -@c time; there are free and strdup calls in there too.  The returned max
> -@c value may change over time for TZNAME_MAX, depending on selected
> -@c timezones; NPROCS, NPROCS_CONF, PHYS_PAGES, AVPHYS_PAGES,
> -@c NGROUPS_MAX, SIGQUEUE_MAX, depending on variable values read from
> -@c /proc at each call, and from rlimit-obtained values CHILD_MAX,
> -@c OPEN_MAX, ARG_MAX, SIGQUEUE_MAX.
> +@c case.  The returned max value may change over time for NPROCS,
> +@c NPROCS_CONF, PHYS_PAGES, AVPHYS_PAGES, NGROUPS_MAX, SIGQUEUE_MAX,
> +@c depending on variable values read from /proc at each call, and from
> +@c rlimit-obtained values CHILD_MAX, OPEN_MAX, ARG_MAX, SIGQUEUE_MAX.
>  This function is used to inquire about runtime system parameters.  The
>  @var{parameter} argument should be one of the @samp{_SC_} symbols listed
>  below.
> diff --git a/posix/sysconf.c b/posix/sysconf.c
> index 0b73b6a..4e9ed97 100644
> --- a/posix/sysconf.c
> +++ b/posix/sysconf.c
> @@ -37,7 +37,7 @@ __sysconf (int name)
>        return -1;
>  
>      case _SC_TZNAME_MAX:
> -      return MAX (__tzname_max (), _POSIX_TZNAME_MAX);
> +      return -1;
>  
>      case _SC_CHARCLASS_NAME_MAX:
>  #ifdef	CHARCLASS_NAME_MAX
> diff --git a/sysdeps/posix/sysconf.c b/sysdeps/posix/sysconf.c
> index 19ed5b0..a95e1b3 100644
> --- a/sysdeps/posix/sysconf.c
> +++ b/sysdeps/posix/sysconf.c
> @@ -93,7 +93,7 @@ __sysconf (int name)
>  #endif
>  
>      case _SC_TZNAME_MAX:
> -      return MAX (__tzname_max (), _POSIX_TZNAME_MAX);
> +      return -1;
>  
>      case _SC_JOB_CONTROL:
>  #if CONF_IS_DEFINED_SET (_POSIX_JOB_CONTROL)
> diff --git a/time/tzfile.c b/time/tzfile.c
> index 4987f1a..d412469 100644
> --- a/time/tzfile.c
> +++ b/time/tzfile.c
> @@ -48,8 +48,6 @@ struct leap
>      long int change;		/* Seconds of correction to apply.  */
>    };
>  
> -static void compute_tzname_max (size_t) internal_function;
> -
>  static size_t num_transitions;
>  libc_freeres_ptr (static time_t *transitions);
>  static unsigned char *type_idxs;
> @@ -494,8 +492,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
>    if (__tzname[1] == NULL)
>      __tzname[1] = __tzname[0];
>  
> -  compute_tzname_max (chars);
> -
>    if (num_transitions == 0)
>      /* Use the first rule (which should also be the only one).  */
>      rule_stdoff = rule_dstoff = types[0].offset;
> @@ -626,8 +622,6 @@ __tzfile_default (const char *std, const char *dst,
>    /* Set the timezone.  */
>    __timezone = -types[0].offset;
>  
> -  compute_tzname_max (stdlen + dstlen);
> -
>    /* Invalidate the tzfile attribute cache to force rereading
>       TZDEFRULES the next time it is used.  */
>    tzfile_dev = 0;
> @@ -836,21 +830,3 @@ __tzfile_compute (time_t timer, int use_localtime,
>  	}
>      }
>  }
> -
> -static void
> -internal_function
> -compute_tzname_max (size_t chars)
> -{
> -  const char *p;
> -
> -  p = zone_names;
> -  do
> -    {
> -      const char *start = p;
> -      while (*p != '\0')
> -	++p;
> -      if ((size_t) (p - start) > __tzname_cur_max)
> -	__tzname_cur_max = p - start;
> -    }
> -  while (++p < &zone_names[chars]);
> -}
> diff --git a/time/tzset.c b/time/tzset.c
> index 262bbe5..f0e5c95 100644
> --- a/time/tzset.c
> +++ b/time/tzset.c
> @@ -68,8 +68,7 @@ static tz_rule tz_rules[2];
>  
>  
>  static void compute_change (tz_rule *rule, int year) __THROW internal_function;
> -static void tzset_internal (int always, int explicit)
> -     __THROW internal_function;
> +static void tzset_internal (int always);
>  
>  /* List of buffers containing time zone strings. */
>  struct tzstring_l
> @@ -126,24 +125,7 @@ __tzstring (const char *s)
>  {
>    return __tzstring_len (s, strlen (s));
>  }
> -
> -/* Maximum length of a timezone name.  tzset_internal keeps this up to date
> -   (never decreasing it) when ! __use_tzfile.
> -   tzfile.c keeps it up to date when __use_tzfile.  */
> -size_t __tzname_cur_max;
>  
> -long int
> -__tzname_max (void)
> -{
> -  __libc_lock_lock (tzset_lock);
> -
> -  tzset_internal (0, 0);
> -
> -  __libc_lock_unlock (tzset_lock);
> -
> -  return __tzname_cur_max;
> -}
> -
>  static char *old_tz;
>  
>  static void
> @@ -154,14 +136,6 @@ update_vars (void)
>    __timezone = -tz_rules[0].offset;
>    __tzname[0] = (char *) tz_rules[0].name;
>    __tzname[1] = (char *) tz_rules[1].name;
> -
> -  /* Keep __tzname_cur_max up to date.  */
> -  size_t len0 = strlen (__tzname[0]);
> -  size_t len1 = strlen (__tzname[1]);
> -  if (len0 > __tzname_cur_max)
> -    __tzname_cur_max = len0;
> -  if (len1 > __tzname_cur_max)
> -    __tzname_cur_max = len1;
>  }
>  
>  
> @@ -390,8 +364,7 @@ __tzset_parse_tz (const char *tz)
>  
>  /* Interpret the TZ envariable.  */
>  static void
> -internal_function
> -tzset_internal (int always, int explicit)
> +tzset_internal (int always)
>  {
>    static int is_initialized;
>    const char *tz;
> @@ -402,12 +375,6 @@ tzset_internal (int always, int explicit)
>  
>    /* Examine the TZ environment variable.  */
>    tz = getenv ("TZ");
> -  if (tz == NULL && !explicit)
> -    /* Use the site-wide default.  This is a file name which means we
> -       would not see changes to the file if we compare only the file
> -       name for change.  We want to notice file changes if tzset() has
> -       been called explicitly.  Leave TZ as NULL in this case.  */
> -    tz = TZDEFAULT;
>    if (tz && *tz == '\0')
>      /* User specified the empty string; use UTC explicitly.  */
>      tz = "Universal";
> @@ -583,7 +550,7 @@ __tzset (void)
>  {
>    __libc_lock_lock (tzset_lock);
>  
> -  tzset_internal (1, 1);
> +  tzset_internal (1);
>  
>    if (!__use_tzfile)
>      {
> @@ -615,7 +582,7 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
>    /* Update internal database according to current TZ setting.
>       POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname.
>       This is a good idea since this allows at least a bit more parallelism.  */
> -  tzset_internal (tp == &_tmbuf && use_localtime, 1);
> +  tzset_internal (tp == &_tmbuf && use_localtime);
>  
>    if (__use_tzfile)
>      __tzfile_compute (*timer, use_localtime, &leap_correction,
>
Mike Frysinger March 13, 2017, 4:32 a.m. UTC | #2
On 07 Mar 2017 10:13, Florian Weimer wrote:
> glibc does not impose a limit, and POSIX does not allow a
> sysconf limit which changes during the lifetime of a process.

i always like deleting code that doesn't remove features :)
-mike
diff mbox

Patch

diff --git a/include/time.h b/include/time.h
index 684ceb8..6badf0e 100644
--- a/include/time.h
+++ b/include/time.h
@@ -37,10 +37,6 @@  extern struct tm _tmbuf attribute_hidden;
 /* Defined in tzset.c.  */
 extern char *__tzstring (const char *string);
 
-/* Defined in tzset.c. */
-extern size_t __tzname_cur_max attribute_hidden;
-
-
 extern int __use_tzfile attribute_hidden;
 
 extern void __tzfile_read (const char *file, size_t extra,
@@ -82,10 +78,6 @@  extern void __tzset (void);
 /* Prototype for the internal function to get information based on TZ.  */
 extern struct tm *__tz_convert (const time_t *timer, int use_localtime, struct tm *tp);
 
-/* Return the maximum length of a timezone name.
-   This is what `sysconf (_SC_TZNAME_MAX)' does.  */
-extern long int __tzname_max (void);
-
 extern int __nanosleep (const struct timespec *__requested_time,
 			struct timespec *__remaining);
 libc_hidden_proto (__nanosleep)
diff --git a/manual/conf.texi b/manual/conf.texi
index 78b7a4d..1fe75c2 100644
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -291,14 +291,10 @@  constants are declared in the header file @file{unistd.h}.
 @safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
 @c Some parts of the implementation open /proc and /sys files and dirs
 @c to collect system details, using fd and stream I/O depending on the
-@c case.  _SC_TZNAME_MAX calls __tzname_max, that (while holding a lock)
-@c calls tzset_internal, that calls getenv if it's called the first
-@c time; there are free and strdup calls in there too.  The returned max
-@c value may change over time for TZNAME_MAX, depending on selected
-@c timezones; NPROCS, NPROCS_CONF, PHYS_PAGES, AVPHYS_PAGES,
-@c NGROUPS_MAX, SIGQUEUE_MAX, depending on variable values read from
-@c /proc at each call, and from rlimit-obtained values CHILD_MAX,
-@c OPEN_MAX, ARG_MAX, SIGQUEUE_MAX.
+@c case.  The returned max value may change over time for NPROCS,
+@c NPROCS_CONF, PHYS_PAGES, AVPHYS_PAGES, NGROUPS_MAX, SIGQUEUE_MAX,
+@c depending on variable values read from /proc at each call, and from
+@c rlimit-obtained values CHILD_MAX, OPEN_MAX, ARG_MAX, SIGQUEUE_MAX.
 This function is used to inquire about runtime system parameters.  The
 @var{parameter} argument should be one of the @samp{_SC_} symbols listed
 below.
diff --git a/posix/sysconf.c b/posix/sysconf.c
index 0b73b6a..4e9ed97 100644
--- a/posix/sysconf.c
+++ b/posix/sysconf.c
@@ -37,7 +37,7 @@  __sysconf (int name)
       return -1;
 
     case _SC_TZNAME_MAX:
-      return MAX (__tzname_max (), _POSIX_TZNAME_MAX);
+      return -1;
 
     case _SC_CHARCLASS_NAME_MAX:
 #ifdef	CHARCLASS_NAME_MAX
diff --git a/sysdeps/posix/sysconf.c b/sysdeps/posix/sysconf.c
index 19ed5b0..a95e1b3 100644
--- a/sysdeps/posix/sysconf.c
+++ b/sysdeps/posix/sysconf.c
@@ -93,7 +93,7 @@  __sysconf (int name)
 #endif
 
     case _SC_TZNAME_MAX:
-      return MAX (__tzname_max (), _POSIX_TZNAME_MAX);
+      return -1;
 
     case _SC_JOB_CONTROL:
 #if CONF_IS_DEFINED_SET (_POSIX_JOB_CONTROL)
diff --git a/time/tzfile.c b/time/tzfile.c
index 4987f1a..d412469 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -48,8 +48,6 @@  struct leap
     long int change;		/* Seconds of correction to apply.  */
   };
 
-static void compute_tzname_max (size_t) internal_function;
-
 static size_t num_transitions;
 libc_freeres_ptr (static time_t *transitions);
 static unsigned char *type_idxs;
@@ -494,8 +492,6 @@  __tzfile_read (const char *file, size_t extra, char **extrap)
   if (__tzname[1] == NULL)
     __tzname[1] = __tzname[0];
 
-  compute_tzname_max (chars);
-
   if (num_transitions == 0)
     /* Use the first rule (which should also be the only one).  */
     rule_stdoff = rule_dstoff = types[0].offset;
@@ -626,8 +622,6 @@  __tzfile_default (const char *std, const char *dst,
   /* Set the timezone.  */
   __timezone = -types[0].offset;
 
-  compute_tzname_max (stdlen + dstlen);
-
   /* Invalidate the tzfile attribute cache to force rereading
      TZDEFRULES the next time it is used.  */
   tzfile_dev = 0;
@@ -836,21 +830,3 @@  __tzfile_compute (time_t timer, int use_localtime,
 	}
     }
 }
-
-static void
-internal_function
-compute_tzname_max (size_t chars)
-{
-  const char *p;
-
-  p = zone_names;
-  do
-    {
-      const char *start = p;
-      while (*p != '\0')
-	++p;
-      if ((size_t) (p - start) > __tzname_cur_max)
-	__tzname_cur_max = p - start;
-    }
-  while (++p < &zone_names[chars]);
-}
diff --git a/time/tzset.c b/time/tzset.c
index 262bbe5..f0e5c95 100644
--- a/time/tzset.c
+++ b/time/tzset.c
@@ -68,8 +68,7 @@  static tz_rule tz_rules[2];
 
 
 static void compute_change (tz_rule *rule, int year) __THROW internal_function;
-static void tzset_internal (int always, int explicit)
-     __THROW internal_function;
+static void tzset_internal (int always);
 
 /* List of buffers containing time zone strings. */
 struct tzstring_l
@@ -126,24 +125,7 @@  __tzstring (const char *s)
 {
   return __tzstring_len (s, strlen (s));
 }
-
-/* Maximum length of a timezone name.  tzset_internal keeps this up to date
-   (never decreasing it) when ! __use_tzfile.
-   tzfile.c keeps it up to date when __use_tzfile.  */
-size_t __tzname_cur_max;
 
-long int
-__tzname_max (void)
-{
-  __libc_lock_lock (tzset_lock);
-
-  tzset_internal (0, 0);
-
-  __libc_lock_unlock (tzset_lock);
-
-  return __tzname_cur_max;
-}
-
 static char *old_tz;
 
 static void
@@ -154,14 +136,6 @@  update_vars (void)
   __timezone = -tz_rules[0].offset;
   __tzname[0] = (char *) tz_rules[0].name;
   __tzname[1] = (char *) tz_rules[1].name;
-
-  /* Keep __tzname_cur_max up to date.  */
-  size_t len0 = strlen (__tzname[0]);
-  size_t len1 = strlen (__tzname[1]);
-  if (len0 > __tzname_cur_max)
-    __tzname_cur_max = len0;
-  if (len1 > __tzname_cur_max)
-    __tzname_cur_max = len1;
 }
 
 
@@ -390,8 +364,7 @@  __tzset_parse_tz (const char *tz)
 
 /* Interpret the TZ envariable.  */
 static void
-internal_function
-tzset_internal (int always, int explicit)
+tzset_internal (int always)
 {
   static int is_initialized;
   const char *tz;
@@ -402,12 +375,6 @@  tzset_internal (int always, int explicit)
 
   /* Examine the TZ environment variable.  */
   tz = getenv ("TZ");
-  if (tz == NULL && !explicit)
-    /* Use the site-wide default.  This is a file name which means we
-       would not see changes to the file if we compare only the file
-       name for change.  We want to notice file changes if tzset() has
-       been called explicitly.  Leave TZ as NULL in this case.  */
-    tz = TZDEFAULT;
   if (tz && *tz == '\0')
     /* User specified the empty string; use UTC explicitly.  */
     tz = "Universal";
@@ -583,7 +550,7 @@  __tzset (void)
 {
   __libc_lock_lock (tzset_lock);
 
-  tzset_internal (1, 1);
+  tzset_internal (1);
 
   if (!__use_tzfile)
     {
@@ -615,7 +582,7 @@  __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
   /* Update internal database according to current TZ setting.
      POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname.
      This is a good idea since this allows at least a bit more parallelism.  */
-  tzset_internal (tp == &_tmbuf && use_localtime, 1);
+  tzset_internal (tp == &_tmbuf && use_localtime);
 
   if (__use_tzfile)
     __tzfile_compute (*timer, use_localtime, &leap_correction,